package com.sharesrc.jdev.wiimotedemo;

import wiiusej.WiiUseApiManager;
import wiiusej.Wiimote;
import wiiusej.wiiusejevents.physicalevents.ExpansionEvent;
import wiiusej.wiiusejevents.physicalevents.IREvent;
import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent;
import wiiusej.wiiusejevents.physicalevents.WiimoteButtonsEvent;
import wiiusej.wiiusejevents.utils.WiimoteListener;
import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerInsertedEvent;
import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerRemovedEvent;
import wiiusej.wiiusejevents.wiiuseapievents.DisconnectionEvent;
import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroInsertedEvent;
import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroRemovedEvent;
import wiiusej.wiiusejevents.wiiuseapievents.NunchukInsertedEvent;
import wiiusej.wiiusejevents.wiiuseapievents.NunchukRemovedEvent;
import wiiusej.wiiusejevents.wiiuseapievents.StatusEvent;

import com.sharesrc.jdev.wiimotedemo.views.MainFrame;

public enum WiiUseJ implements WiimoteListener {

	INSTANCE;

	Wiimote wiimote;
	WiiUseJToWiigeeEventsDispatcher dispatcher = WiiUseJToWiigeeEventsDispatcher.INSTANCE;
	MainFrame gui;
	StatusEvent status;
	boolean isFirstConnect;

	synchronized public StatusEvent getStatus() {
		return this.status;
	}

	synchronized public void setStatus(StatusEvent evt) {
		this.status = evt;
	}

	public boolean isFirstConnect() {
		return this.isFirstConnect;
	}

	public void setFirstConnect(boolean isFirstConnect) {
		this.isFirstConnect = isFirstConnect;
	}

	private WiiUseJ() {
		this.isFirstConnect = true;
	}

	public void init(MainFrame gui) {
		this.gui = gui;
	}

	private void initWiimote() {
		this.wiimote.deactivateContinuous();
		this.wiimote.deactivateSmoothing();
		this.wiimote.setScreenAspectRatio169();
		this.wiimote.setSensorBarBelowScreen();
	}

	private void registerListeners() {
		this.wiimote.addWiiMoteEventListeners(this.gui.getAccelerationPanel());
		this.wiimote.addWiiMoteEventListeners(this.gui.getOrientationPanel());
		this.wiimote.addWiiMoteEventListeners(this.gui.getGravityForcePanel());
		this.wiimote.addWiiMoteEventListeners(this.gui.getWiimotePanel());
		this.wiimote.addWiiMoteEventListeners(this);
	}

	private void unregisterListeners() {
		this.wiimote.removeWiiMoteEventListeners(this.gui.getAccelerationPanel());
		this.wiimote.removeWiiMoteEventListeners(this.gui.getOrientationPanel());
		this.wiimote.removeWiiMoteEventListeners(this.gui.getGravityForcePanel());
		this.wiimote.removeWiiMoteEventListeners(this.gui.getWiimotePanel());
		this.wiimote.removeWiiMoteEventListeners(this);
	}

	public boolean connectWiimote() {
		if (!isFirstConnect()) {
			StatusEvent status = getStatus();
			if (status.isConnected()) {
				return false;
			}
			WiiUseApiManager.shutdown();
			if (this.wiimote != null) {
				disconnectWiimote();
			}
		}

		Wiimote[] listWiimote = WiiUseApiManager.getWiimotes(1, true);
		if (listWiimote != null && listWiimote.length > 0) {
			this.wiimote = listWiimote[0];
			registerListeners();
			initWiimote();
			setFirstConnect(false);
			return true;
		}

		return false;
	}

	public void disconnectWiimote() {
		if (this.wiimote != null) {
			unregisterListeners();
			this.wiimote.disconnect();
		}
		setFirstConnect(true);
	}

	public void setMotionSensingTracking(boolean isActive) {
		if (this.wiimote != null) {
			if (isActive) {
				this.wiimote.activateMotionSensing();
			} else {
				this.wiimote.deactivateMotionSensing();
			}
		}
	}

	@Override
	public void onButtonsEvent(WiimoteButtonsEvent e) {
		// TODO must implement here
		if (e.getButtonsJustPressed() != 0) {
			this.dispatcher.dispatchButtonPressEvent(e);
			this.gui.switchContent(e.getButtonsJustPressed());
		} else if (e.getButtonsJustReleased() != 0) {
			this.dispatcher.dispatchButtonReleaseEvent(e);
		}
	}

	@Override
	public void onIrEvent(IREvent e) {

	}

	@Override
	public void onMotionSensingEvent(MotionSensingEvent e) {
		// TODO must implement here
		this.dispatcher.dispatchAccelerationEvent(e);
		this.dispatcher.dispatchRotationEvent(e);
	}

	@Override
	public void onExpansionEvent(ExpansionEvent e) {

	}

	@Override
	public void onStatusEvent(StatusEvent e) {
		setStatus(e);
	}

	@Override
	public void onDisconnectionEvent(DisconnectionEvent e) {

	}

	@Override
	public void onNunchukInsertedEvent(NunchukInsertedEvent e) {

	}

	@Override
	public void onNunchukRemovedEvent(NunchukRemovedEvent e) {

	}

	@Override
	public void onGuitarHeroInsertedEvent(GuitarHeroInsertedEvent e) {

	}

	@Override
	public void onGuitarHeroRemovedEvent(GuitarHeroRemovedEvent e) {

	}

	@Override
	public void onClassicControllerInsertedEvent(ClassicControllerInsertedEvent e) {

	}

	@Override
	public void onClassicControllerRemovedEvent(ClassicControllerRemovedEvent e) {

	}
}
